package com.ibm.risk.irmp.base.auth.service.impl;

import com.ibm.risk.irmp.base.auth.dao.SystemPermissionRepository;
import com.ibm.risk.irmp.base.auth.dao.SystemRolePermissionRepository;
import com.ibm.risk.irmp.base.auth.dao.SystemRoleRepository;
import com.ibm.risk.irmp.base.auth.entity.SystemPermission;
import com.ibm.risk.irmp.base.auth.entity.SystemRolePermission;
import com.ibm.risk.irmp.base.auth.service.IMenuManagementService;
import com.ibm.risk.irmp.base.auth.vo.UserMenuTreeVo;
import com.ibm.risk.irmp.common.auth.AuthUtils;
import com.ibm.risk.irmp.common.auth.vo.LoginUser;
import com.ibm.risk.irmp.common.exception.BusinessException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cglib.beans.BeanCopier;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Service
@Transactional(readOnly = false)
public class MenuManagementServiceImpl implements IMenuManagementService {

    @Autowired
    private SystemPermissionRepository permissionRepository;
    @Autowired
    private SystemRoleRepository roleRepository;

    @Autowired
    private SystemRolePermissionRepository rolePermissionRepository;

    /**
     * 获取菜单列表
     */
    @Override
    @Transactional(readOnly = true)
    public List<UserMenuTreeVo> getMenuList() {
        //查询菜单列表
        List<SystemPermission> list = permissionRepository.findAll(Sort.by(Sort.Direction.ASC, "sortOrder"));
        return buildMenuTree(list, null);
    }
    private BeanCopier bc = BeanCopier.create(SystemPermission.class, UserMenuTreeVo.class, false);

    private List<UserMenuTreeVo> buildMenuTree(Collection<SystemPermission> permissions, Object parentId) {
        Stream<UserMenuTreeVo> ps = permissions.stream().filter(p -> Objects.equals(p.getParentId(), parentId))
                .map(p1 -> {
                    UserMenuTreeVo um = new UserMenuTreeVo();
                    bc.copy(p1, um, null);
                    List<UserMenuTreeVo> children = buildMenuTree(permissions, um.getPmsId());
                    children.sort(Comparator.comparing(UserMenuTreeVo::getSortOrder));
                    um.setChildren(children);
                    return um;
                });
        return ps.sorted(Comparator.comparing(UserMenuTreeVo::getSortOrder)).collect(Collectors.toList());
    }

//    /**
//     * 构建菜单树Json数组
//     */
//    private List<Map<String, Object>> buildDataTree(List<SystemPermission> dataTypes, String pid) {
//        //树形目录下拉框
//        List<Map<String, Object>> params = new ArrayList();
//        for (SystemPermission entity : dataTypes) {
//            if (Objects.equals(pid, entity.getParentId())) {
//                Map<String, Object> item = new HashMap<>();
//                item.put("key", entity.getPmsId().toString());
//                item.put("parentId", entity.getParentId());
//                item.put("pmsName", entity.getPmsName());
//                item.put("pmsUrl", entity.getPmsUrl());
//                item.put("pmsStatus", entity.getPmsStatus());
//                item.put("icon", entity.getIcon());
//                item.put("sortOrder", entity.getSortOrder());
//
//                List children = new ArrayList();
//                if (entity.getPmsId() != null) {
//                    children = buildDataTree(dataTypes, entity.getPmsId().toString());
//                }
//                if (!children.isEmpty()) {
//                    item.put("children", children);
//                }
//
//                params.add(item);
//            }
//        }
//        return params;
//    }

    /**
     * 保存菜单
     */
    @Override
    public Boolean saveMenu(SystemPermission entity) {
        SystemPermission pEntity = new SystemPermission();
        //数据存在时，更新数据
        if (entity.getPmsId() != null) {
            Optional<SystemPermission> optional = permissionRepository.findById(entity.getPmsId());
            if (optional.isPresent()) {
                pEntity = optional.get();
                pEntity.setPmsName(entity.getPmsName());
                pEntity.setPmsUrl(entity.getPmsUrl());
                pEntity.setPmsStatus(entity.getPmsStatus());
                if (StringUtils.isNotEmpty(entity.getIcon()) && !entity.getIcon().contains("anticon")) {
                    pEntity.setIcon("anticon-" + entity.getIcon());
                } else {
                    pEntity.setIcon(entity.getIcon());
                }
                if (entity.getSortOrder() == null) {
                    pEntity.setSortOrder(0L);
                } else {
                    pEntity.setSortOrder(entity.getSortOrder());
                }
//                pEntity.setUpdateDate(DateFormatUtils.format(new Date(), "yyyyMMdd"));
//                pEntity.setUpdaterId(JWTUtil.getCurrentUserId());
            } else {
                throw new BusinessException("更新的数据不存在");
            }
            //新增数据
        } else {
            if (StringUtils.isNotEmpty(entity.getIcon()) && !entity.getIcon().contains("anticon")) {
                entity.setIcon("anticon-" + entity.getIcon());
            }
            if (entity.getSortOrder() == null) {
                entity.setSortOrder(0L);
            }
//            entity.setCreateDate(DateFormatUtils.format(new Date(), "yyyyMMdd"));
//            entity.setCreatorId(JWTUtil.getCurrentUserId());
            entity.setPmsType("T");
            entity.setPmsBuildin("T");
            pEntity = entity;
        }

        permissionRepository.save(pEntity);

        return true;
    }

    /**
     * 删除菜单
     */
    @Transactional
    public Boolean deleteMenu(Long id) {
        if (id == null) {
            throw new BusinessException("请指定要删除的菜单");
        }
        SystemPermission entity = new SystemPermission();
        entity.setParentId(id);
        List<SystemPermission> list = permissionRepository.findAll(Example.of(entity));
        if (list != null && list.size() > 0) {
            throw new BusinessException("菜单下面有子菜单，不允许删除");
        }

        permissionRepository.deleteById(Long.valueOf(id));

        return true;
    }

    /**
     * 读取用户已授权访问的功能菜单
     *
     * @param username
     */
//    @Cacheable(cacheNames = "IrmpLoginDataCache", key = "methodName + args")
    @Transactional(readOnly = true)
    public List<UserMenuTreeVo> buildUserMenu(String username) {
        if (username == null) {
            throw new BusinessException("请正常登录后进行访问");
        }
        LoginUser user = AuthUtils.getLoginUser();
        Set<SystemPermission> permissions = new HashSet<>();
        user.getRoles().stream().forEach(r -> {
            List<SystemRolePermission> rperms = rolePermissionRepository.findByRoleCodeAndDataType(r.getRoleCode(), SystemRolePermission.ENUM_FUNCTION_TYPE.MENU.getCode());
            List<SystemPermission> perms = permissionRepository.findAllById(rperms.stream().map(rp -> rp.getPmsId()).toList());
            permissions.addAll(perms);
        });
        //Oracle
//        String sql = "SELECT DISTINCT CONNECT_BY_ROOT(pms_id) AS pms_id, CONNECT_BY_ROOT(T.parent_id) parent_id, CONNECT_BY_ROOT(T.pms_name) pms_name,\n" +
//                "  CONNECT_BY_ROOT(T.pms_url) pms_url,CONNECT_BY_ROOT(T.icon) icon,CONNECT_BY_ROOT(T.sort_order) sort_order\n" +
//                " FROM RI_BASE_AUTH_PERMISSION T\n" +
//                " WHERE T.pms_type = 'T' and T.pms_status = 'T' AND T.pms_id IN (\n" +
//                "  select distinct rp.pms_id from RI_BASE_AUTH_ROLE_PERMISSION rp\n" +
//                "   inner join RI_BASE_AUTH_ROLE_USER ru on ru.role_code = rp.role_code\n" +
//                "   inner join RI_BASE_AUTH_USER u on ru.user_id = u.user_id\n" +
//                "  where rp.data_type='menu' and u.user_status = 'T' and u.user_name = :username\n" +
//                ")\n" +
//                " CONNECT BY PRIOR T.pms_id = T.parent_id\n" +
//                " ORDER BY parent_id, sort_order";
        //Gauss

        List<UserMenuTreeVo> menus = buildMenuTree(permissions, null);
        return menus;
    }

}
